-- Copyright (c) 2024 Huawei Technologies Co., Ltd.
-- openUBMC is licensed under Mulan PSL v2.
-- You can use this software according to the terms and conditions of the Mulan PSL v2.
-- You may obtain a copy of Mulan PSL v2 at:
--          http://license.coscl.org.cn/MulanPSL2
-- THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
-- EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
-- MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
-- See the Mulan PSL v2 for more details.
local validate = require 'mc.validate'
local utils = require 'mc.utils'
local mdb = require 'mc.mdb'

local MeasurementSet = {}

---@class MeasurementSet.SummaryHash
---@field SummaryHash string
local TSummaryHash = {}
TSummaryHash.__index = TSummaryHash
TSummaryHash.group = {}

local function TSummaryHash_from_obj(obj)
    return setmetatable(obj, TSummaryHash)
end

function TSummaryHash.new(SummaryHash)
    return TSummaryHash_from_obj({SummaryHash = SummaryHash})
end
---@param obj MeasurementSet.SummaryHash
function TSummaryHash:init_from_obj(obj)
    self.SummaryHash = obj.SummaryHash
end

function TSummaryHash:remove_error_props(errs, obj)
    utils.remove_obj_error_property(obj, errs, TSummaryHash.group)
end

TSummaryHash.from_obj = TSummaryHash_from_obj

TSummaryHash.proto_property = {'SummaryHash'}

TSummaryHash.default = {''}

TSummaryHash.struct = {{name = 'SummaryHash', is_array = false, struct = nil}}

function TSummaryHash:validate(prefix, errs, need_convert)
    prefix = prefix or ''

    validate.Optional(prefix .. 'SummaryHash', self.SummaryHash, 'string', true, errs, need_convert)

    TSummaryHash:remove_error_props(errs, self)
    validate.CheckUnknowProperty(self, TSummaryHash.proto_property, errs, need_convert)
    return self
end

function TSummaryHash:unpack(_)
    return self.SummaryHash
end

MeasurementSet.SummaryHash = TSummaryHash

---@class MeasurementSet.SummaryHashAlgorithm
---@field SummaryHashAlgorithm string
local TSummaryHashAlgorithm = {}
TSummaryHashAlgorithm.__index = TSummaryHashAlgorithm
TSummaryHashAlgorithm.group = {}

local function TSummaryHashAlgorithm_from_obj(obj)
    return setmetatable(obj, TSummaryHashAlgorithm)
end

function TSummaryHashAlgorithm.new(SummaryHashAlgorithm)
    return TSummaryHashAlgorithm_from_obj({SummaryHashAlgorithm = SummaryHashAlgorithm})
end
---@param obj MeasurementSet.SummaryHashAlgorithm
function TSummaryHashAlgorithm:init_from_obj(obj)
    self.SummaryHashAlgorithm = obj.SummaryHashAlgorithm
end

function TSummaryHashAlgorithm:remove_error_props(errs, obj)
    utils.remove_obj_error_property(obj, errs, TSummaryHashAlgorithm.group)
end

TSummaryHashAlgorithm.from_obj = TSummaryHashAlgorithm_from_obj

TSummaryHashAlgorithm.proto_property = {'SummaryHashAlgorithm'}

TSummaryHashAlgorithm.default = {''}

TSummaryHashAlgorithm.struct = {{name = 'SummaryHashAlgorithm', is_array = false, struct = nil}}

function TSummaryHashAlgorithm:validate(prefix, errs, need_convert)
    prefix = prefix or ''

    validate.Optional(prefix .. 'SummaryHashAlgorithm', self.SummaryHashAlgorithm, 'string', true, errs, need_convert)

    TSummaryHashAlgorithm:remove_error_props(errs, self)
    validate.CheckUnknowProperty(self, TSummaryHashAlgorithm.proto_property, errs, need_convert)
    return self
end

function TSummaryHashAlgorithm:unpack(_)
    return self.SummaryHashAlgorithm
end

MeasurementSet.SummaryHashAlgorithm = TSummaryHashAlgorithm

---@class MeasurementSet.SummaryType
---@field SummaryType string
local TSummaryType = {}
TSummaryType.__index = TSummaryType
TSummaryType.group = {}

local function TSummaryType_from_obj(obj)
    return setmetatable(obj, TSummaryType)
end

function TSummaryType.new(SummaryType)
    return TSummaryType_from_obj({SummaryType = SummaryType})
end
---@param obj MeasurementSet.SummaryType
function TSummaryType:init_from_obj(obj)
    self.SummaryType = obj.SummaryType
end

function TSummaryType:remove_error_props(errs, obj)
    utils.remove_obj_error_property(obj, errs, TSummaryType.group)
end

TSummaryType.from_obj = TSummaryType_from_obj

TSummaryType.proto_property = {'SummaryType'}

TSummaryType.default = {''}

TSummaryType.struct = {{name = 'SummaryType', is_array = false, struct = nil}}

function TSummaryType:validate(prefix, errs, need_convert)
    prefix = prefix or ''

    validate.Optional(prefix .. 'SummaryType', self.SummaryType, 'string', true, errs, need_convert)

    if self.SummaryType ~= nil then
        validate.Enum(prefix .. 'SummaryType', self.SummaryType, '', {'All', 'TCB'}, errs, need_convert)
    end

    TSummaryType:remove_error_props(errs, self)
    validate.CheckUnknowProperty(self, TSummaryType.proto_property, errs, need_convert)
    return self
end

function TSummaryType:unpack(_)
    return self.SummaryType
end

MeasurementSet.SummaryType = TSummaryType

---@class MeasurementSet.Specification
---@field Specification string
local TSpecification = {}
TSpecification.__index = TSpecification
TSpecification.group = {}

local function TSpecification_from_obj(obj)
    return setmetatable(obj, TSpecification)
end

function TSpecification.new(Specification)
    return TSpecification_from_obj({Specification = Specification})
end
---@param obj MeasurementSet.Specification
function TSpecification:init_from_obj(obj)
    self.Specification = obj.Specification
end

function TSpecification:remove_error_props(errs, obj)
    utils.remove_obj_error_property(obj, errs, TSpecification.group)
end

TSpecification.from_obj = TSpecification_from_obj

TSpecification.proto_property = {'Specification'}

TSpecification.default = {''}

TSpecification.struct = {{name = 'Specification', is_array = false, struct = nil}}

function TSpecification:validate(prefix, errs, need_convert)
    prefix = prefix or ''

    validate.Optional(prefix .. 'Specification', self.Specification, 'string', true, errs, need_convert)

    if self.Specification ~= nil then
        validate.Enum(prefix .. 'Specification', self.Specification, '', {'DMTF'}, errs, need_convert)
    end

    TSpecification:remove_error_props(errs, self)
    validate.CheckUnknowProperty(self, TSpecification.proto_property, errs, need_convert)
    return self
end

function TSpecification:unpack(_)
    return self.Specification
end

MeasurementSet.Specification = TSpecification

---@class MeasurementSet.SPDMGetSignedMeasurementsRsp
---@field Version string
---@field PublicKey string
---@field HashingAlgorithm string
---@field SigningAlgorithm string
---@field SignedMeasurements string
local TSPDMGetSignedMeasurementsRsp = {}
TSPDMGetSignedMeasurementsRsp.__index = TSPDMGetSignedMeasurementsRsp
TSPDMGetSignedMeasurementsRsp.group = {}

local function TSPDMGetSignedMeasurementsRsp_from_obj(obj)
    return setmetatable(obj, TSPDMGetSignedMeasurementsRsp)
end

function TSPDMGetSignedMeasurementsRsp.new(Version, PublicKey, HashingAlgorithm, SigningAlgorithm, SignedMeasurements)
    return TSPDMGetSignedMeasurementsRsp_from_obj({
        Version = Version,
        PublicKey = PublicKey,
        HashingAlgorithm = HashingAlgorithm,
        SigningAlgorithm = SigningAlgorithm,
        SignedMeasurements = SignedMeasurements
    })
end
---@param obj MeasurementSet.SPDMGetSignedMeasurementsRsp
function TSPDMGetSignedMeasurementsRsp:init_from_obj(obj)
    self.Version = obj.Version
    self.PublicKey = obj.PublicKey
    self.HashingAlgorithm = obj.HashingAlgorithm
    self.SigningAlgorithm = obj.SigningAlgorithm
    self.SignedMeasurements = obj.SignedMeasurements
end

function TSPDMGetSignedMeasurementsRsp:remove_error_props(errs, obj)
    utils.remove_obj_error_property(obj, errs, TSPDMGetSignedMeasurementsRsp.group)
end

TSPDMGetSignedMeasurementsRsp.from_obj = TSPDMGetSignedMeasurementsRsp_from_obj

TSPDMGetSignedMeasurementsRsp.proto_property = {
    'Version', 'PublicKey', 'HashingAlgorithm', 'SigningAlgorithm', 'SignedMeasurements'
}

TSPDMGetSignedMeasurementsRsp.default = {'', '', '', '', ''}

TSPDMGetSignedMeasurementsRsp.struct = {
    {name = 'Version', is_array = false, struct = nil}, {name = 'PublicKey', is_array = false, struct = nil},
    {name = 'HashingAlgorithm', is_array = false, struct = nil},
    {name = 'SigningAlgorithm', is_array = false, struct = nil},
    {name = 'SignedMeasurements', is_array = false, struct = nil}
}

function TSPDMGetSignedMeasurementsRsp:validate(prefix, errs, need_convert)
    prefix = prefix or ''

    validate.Optional(prefix .. 'Version', self.Version, 'string', false, errs, need_convert)
    validate.Optional(prefix .. 'PublicKey', self.PublicKey, 'string', false, errs, need_convert)
    validate.Optional(prefix .. 'HashingAlgorithm', self.HashingAlgorithm, 'string', false, errs, need_convert)
    validate.Optional(prefix .. 'SigningAlgorithm', self.SigningAlgorithm, 'string', false, errs, need_convert)
    validate.Optional(prefix .. 'SignedMeasurements', self.SignedMeasurements, 'string', false, errs, need_convert)

    TSPDMGetSignedMeasurementsRsp:remove_error_props(errs, self)
    validate.CheckUnknowProperty(self, TSPDMGetSignedMeasurementsRsp.proto_property, errs, need_convert)
    return self
end

function TSPDMGetSignedMeasurementsRsp:unpack(_)
    return self.Version, self.PublicKey, self.HashingAlgorithm, self.SigningAlgorithm, self.SignedMeasurements
end

MeasurementSet.SPDMGetSignedMeasurementsRsp = TSPDMGetSignedMeasurementsRsp

---@class MeasurementSet.SPDMGetSignedMeasurementsReq
---@field MeasurementIndices integer[]
---@field SlotId integer
---@field Nonce string
local TSPDMGetSignedMeasurementsReq = {}
TSPDMGetSignedMeasurementsReq.__index = TSPDMGetSignedMeasurementsReq
TSPDMGetSignedMeasurementsReq.group = {}

local function TSPDMGetSignedMeasurementsReq_from_obj(obj)
    return setmetatable(obj, TSPDMGetSignedMeasurementsReq)
end

function TSPDMGetSignedMeasurementsReq.new(MeasurementIndices, SlotId, Nonce)
    return TSPDMGetSignedMeasurementsReq_from_obj({
        MeasurementIndices = MeasurementIndices,
        SlotId = SlotId,
        Nonce = Nonce
    })
end
---@param obj MeasurementSet.SPDMGetSignedMeasurementsReq
function TSPDMGetSignedMeasurementsReq:init_from_obj(obj)
    self.MeasurementIndices = obj.MeasurementIndices
    self.SlotId = obj.SlotId
    self.Nonce = obj.Nonce
end

function TSPDMGetSignedMeasurementsReq:remove_error_props(errs, obj)
    utils.remove_obj_error_property(obj, errs, TSPDMGetSignedMeasurementsReq.group)
end

TSPDMGetSignedMeasurementsReq.from_obj = TSPDMGetSignedMeasurementsReq_from_obj

TSPDMGetSignedMeasurementsReq.proto_property = {'MeasurementIndices', 'SlotId', 'Nonce'}

TSPDMGetSignedMeasurementsReq.default = {{}, 0, ''}

TSPDMGetSignedMeasurementsReq.struct = {
    {name = 'MeasurementIndices', is_array = true, struct = nil}, {name = 'SlotId', is_array = false, struct = nil},
    {name = 'Nonce', is_array = false, struct = nil}
}

function TSPDMGetSignedMeasurementsReq:validate(prefix, errs, need_convert)
    prefix = prefix or ''

    validate.OptionalArray(prefix .. 'MeasurementIndices', self.MeasurementIndices, 'uint8', false, errs, need_convert)
    validate.Optional(prefix .. 'SlotId', self.SlotId, 'uint8', false, errs, need_convert)
    validate.Optional(prefix .. 'Nonce', self.Nonce, 'string', false, errs, need_convert)

    if self.SlotId ~= nil then
        validate.ranges(prefix .. 'SlotId', self.SlotId, 0, 15, errs, need_convert)
    end
    if self.Nonce ~= nil then
        validate.lens(prefix .. 'Nonce', self.Nonce, 64, 64, errs, need_convert)
    end

    TSPDMGetSignedMeasurementsReq:remove_error_props(errs, self)
    validate.CheckUnknowProperty(self, TSPDMGetSignedMeasurementsReq.proto_property, errs, need_convert)
    return self
end

function TSPDMGetSignedMeasurementsReq:unpack(_)
    return self.MeasurementIndices, self.SlotId, self.Nonce
end

MeasurementSet.SPDMGetSignedMeasurementsReq = TSPDMGetSignedMeasurementsReq

MeasurementSet.interface = mdb.register_interface('bmc.kepler.RoT.ComponentIntegrity.MeasurementSet', {
    Specification = {'s', {}, true, nil, false},
    SummaryType = {'s', {}, true, nil, false},
    SummaryHashAlgorithm = {'s', {}, true, nil, false},
    SummaryHash = {'s', {}, true, nil, false}
}, {SPDMGetSignedMeasurements = {'a{ss}ayys', 'sssss', TSPDMGetSignedMeasurementsReq, TSPDMGetSignedMeasurementsRsp}},
    {})

return MeasurementSet
